[IA64] Emulate PAL_HALT_LIGHT
authorawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Mon, 3 Jul 2006 14:27:24 +0000 (08:27 -0600)
committerawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Mon, 3 Jul 2006 14:27:24 +0000 (08:27 -0600)
Use do_block to emulate Guest PAL_HALT_LIGHT,
whenever there is an interrupt for this vcpu,
this vcpu is woken up.

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
xen/arch/ia64/vmx/pal_emul.c
xen/arch/ia64/vmx/vlsapic.c
xen/arch/ia64/xen/vcpu.c
xen/include/asm-ia64/vcpu.h

index adcc7d21d4278594ffdb15acd70735aafaf1da3d..b1fc8ccba2e1c10d00718fd914640d90ed8f3405 100644 (file)
@@ -24,6 +24,8 @@
 #include <asm/dom_fw.h>
 #include <asm/tlb.h>
 #include <asm/vmx_mm_def.h>
+#include <xen/hypercall.h>
+#include <public/sched.h>
 
 static void
 get_pal_parameters (VCPU *vcpu, UINT64 *gr29,
@@ -123,9 +125,11 @@ pal_halt (VCPU *vcpu) {
 static struct ia64_pal_retval
 pal_halt_light (VCPU *vcpu) {
        struct ia64_pal_retval result;
-
-       result.status= -1; //unimplemented
-
+       
+       if(SPURIOUS_VECTOR==vmx_check_pending_irq(vcpu))
+               do_sched_op_compat(SCHEDOP_block,0);
+           
+       result.status= 0;
        return result;
 }
 
index 48510bfc8cefc089245a1510b37a96c6b5c3360d..4bb022d8cb5725b593d2b78afdef8ec87d662b94 100644 (file)
@@ -103,6 +103,7 @@ static void vtm_timer_fn(void *data)
     vitv = VCPU(vcpu, itv);
     if ( !ITV_IRQ_MASK(vitv) ){
         vmx_vcpu_pend_interrupt(vcpu, vitv & 0xff);
+        vcpu_unblock(vcpu);
     }
     vtm=&(vcpu->arch.arch_vmx.vtm);
     cur_itc = now_itc(vtm);
@@ -551,8 +552,7 @@ void vmx_vcpu_pend_batch_interrupt(VCPU *vcpu, UINT64 *pend_irr)
  * it into the guest. Otherwise, we set the VHPI if vac.a_int=1 so that when 
  * the interrupt becomes unmasked, it gets injected.
  * RETURN:
- *  TRUE:   Interrupt is injected.
- *  FALSE:  Not injected but may be in VHPI when vac.a_int=1
+ *    the highest unmasked interrupt.
  *
  * Optimization: We defer setting the VHPI until the EOI time, if a higher 
  *               priority interrupt is in-service. The idea is to reduce the 
@@ -562,13 +562,15 @@ int vmx_check_pending_irq(VCPU *vcpu)
 {
     uint64_t  spsr, mask;
     int     h_pending, h_inservice;
-    int injected=0;
     uint64_t    isr;
     IA64_PSR    vpsr;
     REGS *regs=vcpu_regs(vcpu);
     local_irq_save(spsr);
     h_pending = highest_pending_irq(vcpu);
-    if ( h_pending == NULL_VECTOR ) goto chk_irq_exit;
+    if ( h_pending == NULL_VECTOR ) {
+        h_pending = SPURIOUS_VECTOR;
+        goto chk_irq_exit;
+    }
     h_inservice = highest_inservice_irq(vcpu);
 
     vpsr.val = vmx_vcpu_get_psr(vcpu);
@@ -578,7 +580,6 @@ int vmx_check_pending_irq(VCPU *vcpu)
         if ( !vpsr.ic )
             panic_domain(regs,"Interrupt when IC=0\n");
         vmx_reflect_interruption(0,isr,0, 12, regs ); // EXT IRQ
-        injected = 1;
     }
     else if ( mask == IRQ_MASKED_BY_INSVC ) {
         // cann't inject VHPI
@@ -591,7 +592,7 @@ int vmx_check_pending_irq(VCPU *vcpu)
 
 chk_irq_exit:
     local_irq_restore(spsr);
-    return injected;
+    return h_pending;
 }
 
 /*
index a7d52e5f4e980bbafa822465ef3acdb0eda1639e..762c84017f66ed9c8db8f133eea6168a40b163b6 100644 (file)
@@ -266,7 +266,6 @@ IA64FAULT vcpu_reset_psr_sm(VCPU *vcpu, UINT64 imm24)
        return IA64_NO_FAULT;
 }
 
-#define SPURIOUS_VECTOR 0xf
 
 IA64FAULT vcpu_set_psr_dt(VCPU *vcpu)
 {
index 1eaaa814109bbea219bc3e024c7e390d14c7f17c..326d651ead393c9ee187872f118d5096083177b0 100644 (file)
@@ -20,6 +20,7 @@ typedef cpu_user_regs_t REGS;
 #define PSCB(_v,_x) VCPU(_v,_x)
 #define PSCBX(_v,_x) (_v->arch._x)
 
+#define SPURIOUS_VECTOR 0xf
 
 /* general registers */
 extern UINT64 vcpu_get_gr(VCPU *vcpu, unsigned long reg);